package br.com.insejeccg.util.bean;

import java.lang.reflect.InvocationTargetException;
import java.util.Locale;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtilsBean;
import org.apache.commons.beanutils.ConvertUtilsBean;
import org.apache.commons.beanutils.Converter;

import br.com.insejeccg.util.bean.convert.BeanHelperConverterUtils;
import br.com.insejeccg.util.message.MessageResources;
import br.com.insejeccg.util.message.MessageResourcesUtil;

/**
 * 
 * Provides a bean manipulation with internationalization and convertion of
 * string types
 * @author Fabrício Silva Epaminondas
 * 
 */
@SuppressWarnings("unchecked")
class BeanHelper {

	private Locale locale;

	private MessageResources messageResources;

	private BeanUtilsBean beanUtils = createBeanUtilsBean();

	public BeanHelper() {
		setLocale(Locale.getDefault());
		setMessageRecourse(MessageResourcesUtil.getDefault());
	}

	public void setLocale(Locale locale) {
		this.locale = locale;
	}

	public void setMessageRecourse(MessageResources messageRes) {
		messageResources = messageRes;
	}

	public Locale getLocale() {
		return locale;
	}

	public MessageResources getMessageResources() {
		return messageResources;
	}

	public void populate(Object object, Map<Object, Object> map)
			throws IllegalAccessException, InvocationTargetException {
		beanUtils.populate(object, map);
	}

	public void copyProperties(Object dest, Object source)
			throws IllegalAccessException, InvocationTargetException {
		beanUtils.copyProperties(dest, source);
	}
	
	public void copyProperty(Object dest,String name, Object source)
		throws IllegalAccessException, InvocationTargetException {
		beanUtils.copyProperty(dest, name, source);
	}

	public void setProperty(Object dest, String property, Object value)
			throws IllegalAccessException, InvocationTargetException {
		beanUtils.setProperty(dest, property, value);
	}

	public Object getProperty(Object dest, String property)
			throws IllegalAccessException, InvocationTargetException,
			NoSuchMethodException {
		return beanUtils.getPropertyUtils().getProperty(dest,  property);
	}
	
	
	public Map describe(Object bean)
	throws IllegalAccessException, InvocationTargetException,
	NoSuchMethodException {
		return beanUtils.describe(bean);
	}

	public ConvertUtilsBean getConvertUtils(){
		return beanUtils.getConvertUtils();
	}
	
	public void register(Class clazz, Converter converter){
		((BeanHelperConverterUtils)getConvertUtils()).registerCustomConverter(clazz, converter);
	}
	protected BeanUtilsBean createBeanUtilsBean() {
		BeanUtilsBean beanUtilsBean = new BeanUtilsBean(
				new BeanHelperConverterUtils(), BeanUtilsBean.getInstance()
						.getPropertyUtils());
		
		setApacheConverter(beanUtilsBean);
		return beanUtilsBean;
	}
	
	/**
	 * Inicia os conversosres i18n no beanUtils Garantindo internacionaliza��o e
	 * Muda o ConvertUtil do beanUtils para um tipo que n�o aceita mudar os
	 * conversores
	 */
	public void setApacheConverter(BeanUtilsBean bean) {
		BeanUtilsBean beanUtilsBean = BeanUtilsBean.getInstance();
		if (!(beanUtilsBean.getConvertUtils() instanceof BeanHelperConverterUtils)) {
			BeanUtilsBean.setInstance(bean);
		}
	}

}
